import { DynamicInstanceConfig, GlobalHelp, ModelInstanceHelp } from "@ibiz/dynamic-model-api";
import { AppModelService } from "../model-service";

/**
 * Studio 设计工具动态模型实例沙箱
 *
 * @author chitanda
 * @date 2022-05-23 15:05:21
 * @export
 * @class StudioToolModelServiceSandBox
 */
export class StudioToolModelServiceSandBox {
  protected static instance: StudioToolModelServiceSandBox = new StudioToolModelServiceSandBox();
  /**
   * ModelService 实例缓存
   *
   * @author chitanda
   * @date 2022-05-23 15:05:37
   * @protected
   * @type {Map<string, ModelInstanceHelp>}
   */
  protected helpCache: Map<string, ModelInstanceHelp> = new Map();

  constructor() {
    if (StudioToolModelServiceSandBox.instance) {
      return StudioToolModelServiceSandBox.instance;
    }
  }

  /**
   * 初始化沙箱环境
   *
   * @author chitanda
   * @date 2022-05-23 16:05:01
   * @param {string} appTag 应用标识
   * @param {string} [basePath='./model'] 模型请求根路径, 模型路径后不可以有 /， 正确: ./model 、错误: ./model/
   * @return {*}  {Promise<AppModelService>}
   */
  async initSandBox(appTag: string, basePath: string = './model'): Promise<AppModelService> {
    const service = new AppModelService();
    const help = await GlobalHelp.sandboxInstall(service, async (strPath: string, _config: DynamicInstanceConfig) => {
      let url: string = '';
      url = `${basePath}${strPath}`;
      try {
        const res = await fetch(url);
        if (res.ok) {
          return res.json();
        }
      } catch (error) {
        return null;
      }
    });
    this.helpCache.set(appTag, help);
    return help.getModelService();
  }

  /**
   * 根据应用标识获取模型服务
   *
   * @author chitanda
   * @date 2022-05-23 15:05:33
   * @param {string} appTag
   * @return {*}  {Promise<AppModelService>}
   */
  async getModelService(appTag: string): Promise<AppModelService> {
    const help = this.helpCache.get(appTag);
    if (help) {
      return help.getModelService();
    }
    throw new Error(`未找到对应标识[${appTag}]的ModelService`);
  }

  /**
   * 获取实例
   *
   * @author chitanda
   * @date 2022-05-23 15:05:08
   * @static
   * @return {*}  {StudioToolModelServiceSandBox}
   */
  static getInstance(): StudioToolModelServiceSandBox {
    return this.instance;
  }
}
